package com.jh.user.util;

import com.google.zxing.*;
import com.google.zxing.common.BitMatrix;
import com.swetake.util.Qrcode;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;


/**
 * 二维码生成工具类
 *
 * @author Cloud
 * @data 2016-12-15
 * QRCode
 */
public class QRCodeUtil {

    private static Logger log = LoggerFactory.getLogger(Qrcode.class);

    //二维码颜色
    private static final int BLACK = 0xFF000000;
    //二维码颜色
    private static final int WHITE = 0xFFFFFFFF;

//    public static void main(String[] args) {
//        String contents = "http://192.168.13.102/h5pay/pay.html?platformCode=18800000000000";
//        String outPutPath = "/Users/lichengying/Downloads/QR.jpg";
//        String imageType = "jpg";
//        Map map = new HashMap();
//        map.put("contents", contents);
//        map.put("width", 200);
//        map.put("height", 200);
//        map.put("outPutPath", outPutPath);
//        map.put("imageType", imageType);
//        QRCodeUtil.AddQRCode(map);
//    }

    /**
     * 生成二维码
     * @Date 20180801
     */
    public static void AddQRCode(Map param){
        //二维码内容
        String contents = StringUtils.isBlank(MapUtils.getString(param,"contents")) ? "" : MapUtils.getString(param,"contents");
        //二维码宽
        int width = MapUtils.getInteger(param, "width");
        //二维码高
        int height = MapUtils.getInteger(param, "height");
        //二维码生成保存路径
        String outPutPath = StringUtils.isBlank(MapUtils.getString(param, "outPutPath")) ? "" : MapUtils.getString(param, "outPutPath");
        //二维码生成格式
        String imageType = StringUtils.isBlank(MapUtils.getString(param, "imageType")) ? "" : MapUtils.getString(param,"imageType");
        Map<EncodeHintType, String> paramMap = new HashMap<>();
        //设置编码字符集
        paramMap.put(EncodeHintType.CHARACTER_SET, "utf-8");
        try {
            //1、生成二维码
            BitMatrix encode = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, paramMap);
            //3、将二维码放入缓冲流
            BufferedImage image = new BufferedImage(encode.getWidth(), encode.getHeight(), BufferedImage.TYPE_INT_RGB);
            for (int i = 0; i < encode.getWidth(); i++) {
                for (int j = 0; j < encode.getHeight(); j++) {
                    //4、循环将二维码内容定入图片
                    image.setRGB(i, j, encode.get(i, j) ? BLACK : WHITE);
                }
            }
            File outPutImage = new File(outPutPath);
            //如果图片不存在创建图片
            if (!outPutImage.exists())
                outPutImage.createNewFile();
            //5、将二维码写入图片
            ImageIO.write(image, imageType, outPutImage);
        }catch (WriterException e){
            log.error("二维码生成失败");
            e.printStackTrace();
        }catch (IOException e) {
            log.error("生成二维码图片失败");
            e.printStackTrace();
        }
    }

    /**
     *二维码解析
     * @param analyzePath    二维码路径
     * @return
     */
//    public static Object Analyze(String analyzePath){
//        Object result = null;
//        MultiFormatReader reader = new MultiFormatReader();
//        try {
//            File file = new File(analyzePath);
//            if(!file.exists()){
//                return "二维码不存在！";
//            }
//            BufferedImage image = ImageIO.read(file);
//            LuminanceSource source = new BufferedImageLuminanceSource(image);
//            Binarizer binarizer = new HybridBinarizer(source);
//            BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
//            Map hints = new HashMap();
//            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
//            result = reader.decode(binaryBitmap, hints);
//        }catch (Exception e){
//            log.error("二维码解析失败！");
//            e.printStackTrace();
//        }
//        return result;
//    }

    /**
     * <span style="font-size:18px;font-weight:blod;">QRCode 方式生成二维码</span>
     *
     * @param content 二维码内容
     * @param imgPath 二维码生成路径
     * @param version 二维码版本
     */
    public static void QRCodeCreate(String content, String imgPath, int version, String logoPath) {
        try {
            Qrcode qrcodeHandler = new Qrcode();
            //设置二维码排错率，可选L(7%) M(15%) Q(25%) H(30%)，排错率越高可存储的信息越少，但对二维码清晰度的要求越小
            qrcodeHandler.setQrcodeErrorCorrect('M');
            //N代表数字,A代表字符a-Z,B代表其他字符
            qrcodeHandler.setQrcodeEncodeMode('B');
            //版本1为21*21矩阵，版本每增1，二维码的两个边长都增4；所以版本7为45*45的矩阵；最高版本为是40，是177*177的矩阵
            qrcodeHandler.setQrcodeVersion(version);
            //根据版本计算尺寸
            int imgSize = 67 + 12 * (version - 1);
            byte[] contentBytes = content.getBytes("gb2312");
            BufferedImage bufImg = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB);
            Graphics2D gs = bufImg.createGraphics();
            gs.setBackground(Color.WHITE);
            gs.clearRect(0, 0, imgSize, imgSize);
            // 设定图像颜色 > BLACK
            gs.setColor(Color.BLACK);
            // 设置偏移量 不设置可能导致解析出错
            int pixoff = 2;
            // 输出内容 > 二维码
            if (contentBytes.length > 0 && contentBytes.length < 130) {
                boolean[][] codeOut = qrcodeHandler.calQrcode(contentBytes);
                for (int i = 0; i < codeOut.length; i++) {
                    for (int j = 0; j < codeOut.length; j++) {
                        if (codeOut[j][i]) {
                            gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);
                        }
                    }
                }
            } else {
                log.error("QRCode content bytes length = " + contentBytes.length + " not in [ 0,130 ]. ");
            }
            /* 判断是否需要添加logo图片 */
            if (logoPath != null) {
                File icon = new File(logoPath);
                if (icon.exists()) {
                    int width_4 = imgSize / 4;
                    int width_8 = width_4 / 2;
                    int height_4 = imgSize / 4;
                    int height_8 = height_4 / 2;
                    Image img = ImageIO.read(icon);
                    gs.drawImage(img, width_4 + width_8, height_4 + height_8, width_4, height_4, null);
                    gs.dispose();
                    bufImg.flush();
                } else {
                    log.info("Error: login图片不存在！");
                }

            }
            gs.dispose();
            bufImg.flush();
            //创建二维码文件
            File imgFile = new File(imgPath);
            if (!imgFile.exists())
                imgFile.createNewFile();
            //根据生成图片获取图片
            String imgType = imgPath.substring(imgPath.lastIndexOf(".") + 1, imgPath.length());
            // 生成二维码QRCode图片
            ImageIO.write(bufImg, imgType, imgFile);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("");
        }
    }
}

/**
 * <span style="font-size:18px;font-weight:blod;">QRCode二维码解析</span>
 * @param codePath    二维码路径
 * @return 解析结果
 */
//    public static String QRCodeAnalyze(String codePath) {
//        File imageFile = new File(codePath);
//        BufferedImage bufImg = null;
//        String decodedData = null;
//        try {
//            if(!imageFile.exists())
//                return "二维码不存在";
//            bufImg = ImageIO.read(imageFile);
//
//            QRCodeDecoder decoder = new QRCodeDecoder();
//            decodedData = new String(decoder.decode(new ImageUtil(bufImg)), "utf-8");
//        } catch (IOException e) {
//            System.out.println("Error: " + e.getMessage());
//            e.printStackTrace();
//        } catch (DecodingFailedException dfe) {
//            System.out.println("Error: " + dfe.getMessage());
//            dfe.printStackTrace();
//        }
//        return decodedData;
//    }


